package com.sevntu.apvs.timeChart;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import javax.swing.JScrollBar;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.XYTextAnnotation;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.time.DateRange;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

public class Chart
{
	private String title;
	private String axesX;
	private String axesY;
	private JFreeChart chart;
	private XYPlot plot;
	private ChartPanel chartPanel;
	private NumberAxis numberAxis;
	private ValueAxis valueAxis;
	private ArrayList <ArrayList <Double>> Xpos;
	private ArrayList <pinList> infoList;
	private int circuitList [] = null;
	private boolean itsX [] = null;
	private int time, circuitCount;
	
	public Chart (String title, String axesX, String axesY)
    {
		this.title = title;
	    this.axesX = axesX;
	    this.axesY = axesY;
	    chart = createChart(null);
	    setChartBackground (new Color(238,238,238));
        plot = chart.getXYPlot();
        setPlotBackground (new Color(0,0,0));
        numberAxis = (NumberAxis) plot.getDomainAxis();
        numberAxis.setTickLabelsVisible(false);
        valueAxis = plot.getRangeAxis();
        valueAxis.setTickLabelsVisible(false);
	    chartPanel = new ChartPanel(chart);
	    chartPanel.setPreferredSize(new Dimension(1040, 440));
    }
	
	public Chart (String protocol, String info, String title, String axesX, String axesY, int myList[])
    {
		circuitList = myList;
    	this.title = title;
	    this.axesX = axesX;
	    this.axesY = axesY;
	    Xpos = new ArrayList <ArrayList<Double>>();
	    infoList = new ArrayList <pinList>();
	    buidInfo (info);
	    chart = createChart(createDataset(protocol));
	    setChartBackground (new Color(238,238,238));
        plot = chart.getXYPlot();
        setPlotBackground (new Color(0,0,0));
        numberAxis = (NumberAxis) plot.getDomainAxis();
        numberAxis.setRange(new DateRange(0, 20));
        numberAxis.setTickUnit(new NumberTickUnit(1));
        valueAxis = plot.getRangeAxis();
        valueAxis.setRange(new DateRange(0,9));
        ((NumberAxis) valueAxis).setTickUnit(new NumberTickUnit(1));
	    chartPanel = new ChartPanel(chart);
	    chartPanel.setPreferredSize(new Dimension(1040, 440));
	    for (int i=0;i<plot.getSeriesCount();i++)
	    plot.getRenderer().setSeriesStroke(i, new BasicStroke(3.5f)); 
	    for (int j=0;j<Xpos.size();j++)
	    {
	    	XYTextAnnotation textA = new XYTextAnnotation("X",Xpos.get(j).get(0),Xpos.get(j).get(1));
	        textA.setFont(new Font("Arial Black",Font.BOLD, 22));
	        textA.setPaint(Color.YELLOW);
	        plot.addAnnotation(textA);
	    }
    }
	 
    private JFreeChart createChart(XYDataset data)
    {
        JFreeChart myChart = ChartFactory.createXYLineChart(title, axesX, axesY, data, PlotOrientation.VERTICAL, false, false, false);
        return myChart;
    }
    
    private XYDataset createDataset (String filePath)
    {
    	XYSeriesCollection Data = new XYSeriesCollection();
    	ArrayList <Double> XY;
	    File inputFile =  new File (filePath);
	    if (inputFile.exists())
	    {
	    	String str,Temp[];
		    BufferedReader in = null;
		    boolean firstLine = true;
		    int oldTime = 0;
		    time = 0;
		    circuitCount = 0;
		    try
		    {
		    	in = new BufferedReader(new FileReader(inputFile));
		        while ((str = in.readLine()) != null)
		        {
		        	if (firstLine == true)
		        	{
		        		circuitCount = Integer.parseInt(str);
		        		itsX = new boolean [circuitCount];
		        		for (int i=0;i<circuitCount;i++)
		        		Data.addSeries(new XYSeries("Series " + Integer.toString(i)));
		        		if (circuitList == null) 
		        		{
		        			circuitList = new int [circuitCount];
		        			for (int i=0;i<circuitCount;i++) circuitList [i] = i;
		        		}
		        		firstLine = false;
		        	}
		        	else
		        	{
		        		Temp = str.split("\\s+");
		        		time = Integer.parseInt(Temp[0]);
		        	    for (int i=oldTime;i<time;i++)
		        	    for (int j=0;j<circuitList.length;j++)
		        	    {
		        	    	int index = Data.getSeries(circuitList[j]).getItems().size();
		        	    	if (itsX[j]==true)
		        	    	{
		        	    		XY = new ArrayList <Double>();
		        	    		XY.add(i + 0.5);
		        	    	    XY.add(circuitList[j] + 1.5);
		        	    	    Xpos.add(XY);
		        	    	    if (index != 0)
		        	    	    {
		        	    	    	Data.getSeries(circuitList[j]).add(i,circuitList[j] + 1.2);
		        	    	    	Data.getSeries(circuitList[j]).add(i+1,circuitList[j] + 1.2);
		        	    	    }
		        	    	}
		        	    	else
		        	    	Data.getSeries(circuitList[j]).add(i+1,Data.getSeries(circuitList[j]).getY(index-1));	
		        	    }
		        	    for (int i=0;i<circuitCount;i++) itsX [i] = false;
		        		for (int j=0;j<circuitList.length;j++)
		    	        {
		        			int Value = Integer.parseInt(Temp[circuitList[j]+1]);
		        			if (Value == 0) Data.getSeries(circuitList[j]).add(time, circuitList[j] + 1);
		        			else
		        			if (Value == 1)	Data.getSeries(circuitList[j]).add(time, circuitList[j] + 1.5);
		        			else
		        			{
		        				itsX[j]=true;
		        				XY = new ArrayList <Double>();
		        	    	    XY.add(time + 0.5);
		        	    	    XY.add(circuitList[j] + 1.5);
		        	    	    Xpos.add(XY);
		        			}
		    	        }
		        		oldTime = time;
		        	}
		        }
		    }
		    catch (Exception e)
		    {
			    e.printStackTrace();
	        }
	   }
	   else
	   {
		   JOptionPane.showMessageDialog(new javax.swing.JFrame(),"Входной файл отсутствует !","Сообщение",JOptionPane.ERROR_MESSAGE);
	   }
       return Data;
    }
    
    private int buidInfo (String filePath)
    {
    	File inputFile =  new File (filePath);
 	    if (inputFile.exists())
 	    {
 	    	String str,Temp[];
 		    BufferedReader in = null;
 		    try
 		    {
 		    	in = new BufferedReader(new FileReader(inputFile));
 		        while ((str = in.readLine()) != null)
 		        {
 		        	Temp = str.split("\\s+");
 		        	infoList.add(new pinList(Integer.parseInt(Temp[0]), Temp[1],Integer.parseInt(Temp[2]),
 		        	Integer.parseInt(Temp[3]),Temp[4],Integer.parseInt(Temp[5]),Integer.parseInt(Temp[6])));
 		        }
 		    }
 		    catch (Exception e)
		    {
			    e.printStackTrace();
	        }
 	    }    	
    	return 0;
    }
    
	public JScrollBar getHorizontalScrollBar()
	{
		final double r1 = numberAxis.getLowerBound();
	    final double r2 = numberAxis.getUpperBound();
	    if (time - 20 < 0) time = 0;
	    else time = time - 20;
	    JScrollBar scrollBar = new JScrollBar(JScrollBar.HORIZONTAL,0,0,0,time);
	    scrollBar.setPreferredSize(new Dimension (1080,20));
	    scrollBar.addAdjustmentListener( new AdjustmentListener()
	    {
	    	public void adjustmentValueChanged(AdjustmentEvent e) 
	        {
	    		double x = e.getValue();
	            numberAxis.setRange(r1+x, r2+x+1);
	         }
	    });
	    return scrollBar;
	 }
	
	public JScrollBar getVerticalScrollBar()
	{
		final double r1 = valueAxis.getLowerBound();
	    final double r2 = valueAxis.getUpperBound();
	    if (circuitCount - 9 < 0) circuitCount = 0;
	    else circuitCount = circuitCount - 9;
	    JScrollBar scrollBar = new JScrollBar(JScrollBar.VERTICAL,0,0,0,circuitCount);
	    scrollBar.setPreferredSize(new Dimension (20,400));
	    scrollBar.addAdjustmentListener( new AdjustmentListener()
	    {
	    	public void adjustmentValueChanged(AdjustmentEvent e) 
	        {
	    		double x = e.getValue();
	            valueAxis.setRange(r1+x, r2+x+1);
	         }
	    });
	    return scrollBar;
	 }
	
	public ChartPanel getChart ()
	{
		return chartPanel;
	}
	
	public ArrayList <pinList> getPinList ()
	{
		return infoList;
	}
	
	public void setPlotBackground (Color c)
	{
		plot.setBackgroundPaint(c);
	}
	
	public void setChartBackground (Color c)
	{
		chart.setBackgroundPaint(c);
	}
}